//
// Created by 游钐栗 on 2022/8/19.
//

#ifndef UNTITLED1_EXTRACTAUDIOWND_H
#define UNTITLED1_EXTRACTAUDIOWND_H

#include <QWidget>
#include <cstdio>
#include <cstdlib>
#include <cstring>

extern "C"{
#include <libavutil/log.h>
#include <libavformat/avio.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/frame.h>
#include <libavutil/mem.h>
}

#define ADTS_HEADER_LEN  7
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096

QT_BEGIN_NAMESPACE
namespace Ui { class ExtractAudioWnd; }
QT_END_NAMESPACE

class ExtractAudioWnd : public QWidget {
Q_OBJECT

public:
    explicit ExtractAudioWnd(QWidget *parent = nullptr);
    ~ExtractAudioWnd() override;

    /**
     * aac、mp3格式转pcm解码函数
     * @param dec_ctx
     * @param pkt
     * @param frame
     * @param outfile
     */
    static void decode_audio(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile);

private slots:
    /**
     * 分离aac文件按钮按下
     */
    void aacButton_clicked();

    /**
     * 获取pcm按钮按下
     */
     void pcmButton_clicked();

private:
    /**
     *
     */
    Ui::ExtractAudioWnd *ui;

    /**
     * 由用户自己绑定的信号和槽函数
     */
    void custom_signalslot();

    /**
     * 获取aac文件
     * @param q_filename
     * @return
     */
    int get_aac(QString q_filename);

    /**
     * 将解码前文件(AAC)解码，生成PCM原始数据
     * @param q_filename
     * @return
     */
    int get_pcm(QString q_filename);

    /**
     * 支持的采样频率
     */
    const int sampling_frequencies[12] = {
            96000,  // 0x0
            88200,  // 0x1
            64000,  // 0x2
            48000,  // 0x3
            44100,  // 0x4
            32000,  // 0x5
            24000,  // 0x6
            22050,  // 0x7
            16000,  // 0x8
            12000,  // 0x9
            11025,  // 0xa
            8000   // 0xb
            // 0xc d e f是保留的
    };

    /**
     * 手动添加ADTS header，因为AVStream和AVPacket的信息不是带ADTS header的
     * @param p_adts_header
     * @param data_length
     * @param profile
     * @param samplerate
     * @param channels
     * @return
     */
    int adts_header(char * const p_adts_header, const int data_length,
                    const int profile, const int samplerate,
                    const int channels);
};

#endif